#include "SApplication.h"

#include <bonddict/IBondDict.h>
#include <core/Events.h>
#include <core/ImageMgr.h>
#include <core/StyleMgr.h>

#include <QJsonObject>
#include <QTextCodec>
#include <thread>

#include "CMD/CmdMgr.h"
#include "ModuleMgr.h"
#include "UI/MainFrame.h"

// we can't inherit from QApplication, otherwise it will have problems in Linux
static SApplication* app = nullptr;
IApplication* getAppInstance(int argc, char* argv[]) {
  if (app == nullptr) {
    app = new SApplication(argc, argv);
  }

  return app;
}

IApplication* getAppInstance() { return app; }

void releaseApp() {
  CmdMgr::instance().unInitialize();
  delete app;
}

SApplication::SApplication(int argc, char* argv[]) {
  QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
  QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
  QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
      Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
  // hold the parameters
  m_argc = argc;
  m_argv = argv;
  m_qApp = new QApplication(m_argc, m_argv);
  m_qApp->setStyle("windows");

  QFont font("Microsoft YaHei");
  font.setPixelSize(12);
  m_qApp->setFont(font);

  ImgMgr::instance().registerImgs("guiframe");
  ImgMgr::instance().registerImgs("widgets");
  m_qApp->setStyleSheet(StyleMgr::instance().appStyleSheet());
}

SApplication::~SApplication() {
  if (m_qApp) delete m_qApp;
  m_qApp = nullptr;
}

int SApplication::run() {
  if (m_frame) return -1;

  // TODO: get it from style config
  QPalette pl;
  pl.setColor(QPalette::Window, StyleMgr::instance().color("BasicBackground"));
  pl.setColor(QPalette::Text, StyleMgr::instance().color("TextNormal"));
  pl.setColor(QPalette::WindowText, StyleMgr::instance().color("TextNormal"));
  QApplication::setPalette(pl);
  QApplication::setWindowIcon(QIcon(":/guiframe/qeubee.ico"));

  QTextCodec* gbk = QTextCodec::codecForName("GBK");
  if (gbk == nullptr)
    log_error("NO GBK TextCodec!");
  else
    QTextCodec::setCodecForLocale(gbk);

  log_info("APP:Initialize CMD");
  CmdMgr::instance().initialize();

  log_info("APP:Initialize MainFrame");
  m_frame = new MainFrame();
  m_frame->showMaximized();
  m_frame->setAttribute(Qt::WA_DeleteOnClose);

  widgetEventDispatcher.dispatch(EVENT_FRAME_READY, m_frame);
  log_info("APP:Run");
  return m_qApp->exec();
}

IMainFrame* SApplication::mainFrame() const { return m_frame; }

int /*error_code*/ SApplication::execCommand(int cmd, const char* parameters) {
  QString paraStr = QString::fromUtf8(parameters);
  return CmdMgr::instance().execCmd(cmd, paraStr) ? 0 : -1;
}

int /*error_code*/ SApplication::execCommand(const QString* cmd_name,
                                             const QJsonObject* parameters) {
  if ((*cmd_name) == "accountInfo") {
    const QString& tag = (*parameters)["tag"].toString();
    m_frame->openAccountInfo(tag);
    return 0;
  }

  // if (name == "BrokerBestPrice")
  return CmdMgr::instance().execCmd(cmd_name, parameters) ? 0 : -1;
}

float SApplication::uiScale() {
  // TODO: from configuration
  return m_frame->uiScale();
}
